package com.hs.hlw.credit.system.business.service.impl;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.hs.hlw.credit.system.business.dto.ResponseDto;
import com.hs.hlw.credit.system.business.dto.SubmissionDto;
import com.hs.hlw.credit.system.business.dto.SubmissionFormFieldDto;
import com.hs.hlw.credit.system.business.dto.UserDto;
import com.hs.hlw.credit.system.business.service.SubmissionService;
import com.hs.hlw.credit.system.common.enumeration.*;
import com.hs.hlw.credit.system.common.util.*;
import com.hs.hlw.credit.system.data.DataUtils;
import com.hs.hlw.credit.system.data.mybatis.Pageable;
import com.hs.hlw.credit.system.data.primary.mapper.DataSourceMapper;
import com.hs.hlw.credit.system.data.primary.mapper.SubmissionBatchMapper;
import com.hs.hlw.credit.system.data.primary.mapper.SubmissionFormFieldMapper;
import com.hs.hlw.credit.system.data.primary.mapper.SubmissionFormMapper;
import com.hs.hlw.credit.system.data.primary.model.*;
import com.hs.hlw.credit.system.data.util.CommonDataUtil;
import com.hs.hlw.credit.system.data.util.DbUtil;
import com.hs.hlw.credit.system.data.util.DbUtil_DM;
import com.hualongdata.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.engine.jdbc.batch.spi.Batch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.util.*;

/**
 * SubmissionServiceImpl
 *
 * @author zhb
 * @date 2018/11/22
 */
@Service
public class SubmissionServiceImpl implements SubmissionService {
    private @Autowired SubmissionFormMapper submissionFormMapper;
    private @Autowired DataSourceMapper dataSourceMapper;
    private @Autowired SubmissionFormFieldMapper submissionFormFieldMapper;
    private @Autowired SubmissionBatchMapper submissionBatchMapper;
    @Value("${sftp.server.sftpPath}")
    private String sftpPath;
    @Value("${sftp.server.host}")
    private String host;
    @Value("${sftp.server.port}")
    private Integer port;
    @Value("${sftp.server.username}")
    private String username;
    @Value("${sftp.server.password}")
    private String password;
    /** 草稿.*/
    private static final short ADD_DATA_STATUS_0 = 0;
    /** 非草稿.*/
    private static final short ADD_DATA_STATUS_1 = 1;
    private static final Logger LOGGER = LoggerFactory.getLogger(SubmissionServiceImpl.class);

    /**
     * 单个报送
     * @param data
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDto submit(SubmissionDto.Submit data, UserDto user) {
        // 获取表单信息
        SubmissionForm form = checkSubmissionForm(data.getFormId());

        // 获取数据源信息
        DataSource dataSource = checkDataSource(form.getDataSourceId());

        // 获取字段列表
        List<SubmissionFormField> fieldList = getFieldList(data.getFormId());

        // 校验参数
        JsonObject json = JsonUtil.objToJson(data.getParams());
        List<SubmissionDto.ErrorMsg> errorMsgList = checkParams(fieldList, json, ADD_DATA_STATUS_1);
        if (errorMsgList != null && !errorMsgList.isEmpty()) {
            return new ResponseDto(1, "提交失败", errorMsgList);
        }

        // 获取批次信息
        SubmissionBatch submissionBatch = null;
        if (json.has("ID")) {
            DbUtil dbUtil = CommonDataUtil.getDbUtilInstance(dataSource);
            Pageable pageable = DataUtils.pageable(1, 1, null, null);
            List<SubmissionFormField> whereList = new ArrayList<>();
            SubmissionFormField field = new SubmissionFormField();
            field.setFieldCode("ID");
            field.setFieldValue(json.get("ID").getAsString());
            field.setLogicOperator(LogicOperator.CASE_1.code);
            field.setFieldDataType("VARCHAR");
            whereList.add(field);
            List<Map<String, Object>> dataList = dbUtil.page(form.getTableName(), fieldList, whereList, pageable);
            if (dataList == null || dataList.isEmpty()) {
                throw new BusinessException("数据不存在");
            }
            Map<String, Object> detail = dataList.get(0);
            Integer batchId = detail.get("ADD_BATCH_ID") == null ? null : Integer.parseInt(detail.get("ADD_BATCH_ID").toString());
            if (batchId == null) {
                submissionBatch = saveSubmissionBatch(data.getFormId(), SubmissionBatchType.TYPE_1.code, 1, user);
            } else {
                submissionBatch = submissionBatchMapper.selectByPrimaryKey(batchId);
                if (submissionBatch == null) {
                    submissionBatch = saveSubmissionBatch(data.getFormId(), SubmissionBatchType.TYPE_1.code, 1, user);
                } else {
                    if (!SubmissionBatchStatus.STATUS_0.code.equals(submissionBatch.getStatus())) {
                        throw new BusinessException("非待处理状态的数据，不允许修改");
                    }
                }
            }
        } else {
            submissionBatch = saveSubmissionBatch(data.getFormId(), SubmissionBatchType.TYPE_1.code, 1, user);
        }

        // 保存数据
        JsonArray jsonArray = new JsonArray();
        jsonArray.add(json);
        saveData(dataSource, form, fieldList, submissionBatch, jsonArray, ADD_DATA_STATUS_1);

        return new ResponseDto("提交成功");
    }


    /**
     * 保存草稿
     * @param data
     * @param user
     * @return
     */
    public ResponseDto saveDraft(SubmissionDto.Submit data, UserDto user) {
        // 获取表单信息
        SubmissionForm form = checkSubmissionForm(data.getFormId());

        // 获取数据源信息
        DataSource dataSource = checkDataSource(form.getDataSourceId());

        // 获取字段列表
        List<SubmissionFormField> fieldList = getFieldList(data.getFormId());

        // 校验参数
        JsonObject json = JsonUtil.objToJson(data.getParams());
        List<SubmissionDto.ErrorMsg> errorMsgList = checkParams(fieldList, json, ADD_DATA_STATUS_0);
        if (errorMsgList != null && !errorMsgList.isEmpty()) {
            return new ResponseDto(1, "提交失败", errorMsgList);
        }

        // 获取批次信息
        SubmissionBatch submissionBatch = null;
        if (json.has("ID")) {
            DbUtil dbUtil = CommonDataUtil.getDbUtilInstance(dataSource);
            Pageable pageable = DataUtils.pageable(1, 1, null, null);
            List<SubmissionFormField> whereList = new ArrayList<>();
            SubmissionFormField field = new SubmissionFormField();
            field.setFieldCode("ID");
            field.setFieldValue(json.get("ID").getAsString());
            field.setLogicOperator(LogicOperator.CASE_1.code);
            field.setFieldDataType("VARCHAR");
            whereList.add(field);
            List<Map<String, Object>> dataList = dbUtil.page(form.getTableName(), fieldList, whereList, pageable);
            if (dataList == null || dataList.isEmpty()) {
                throw new BusinessException("数据不存在");
            }
            Map<String, Object> detail = dataList.get(0);
            Integer batchId = detail.get("ADD_BATCH_ID") == null ? null : Integer.parseInt(detail.get("ADD_BATCH_ID").toString());
            if (batchId == null) {
                submissionBatch = new SubmissionBatch();
                submissionBatch.setCreatorId(user.getId());
                submissionBatch.setOrgId(user.getOrgId());
                submissionBatch.setCreatorName(user.getUserName());
                submissionBatch.setOrgName(user.getOrgName());
            } else {
                throw new BusinessException("已上报的数据，不允许保存草稿");
            }
        } else {
            submissionBatch = new SubmissionBatch();
            submissionBatch.setCreatorId(user.getId());
            submissionBatch.setCreatorName(user.getUserName());
            submissionBatch.setOrgId(user.getOrgId());
            submissionBatch.setOrgName(user.getOrgName());
        }

        // 保存数据
        JsonArray jsonArray = new JsonArray();
        jsonArray.add(json);
        saveData(dataSource, form, fieldList, submissionBatch, jsonArray, ADD_DATA_STATUS_0);

        return new ResponseDto("提交成功");
    }


    /**
     * 批量删除草稿
     * @param data
     * @return
     */
    public ResponseDto batchDeleteDraft(SubmissionDto.BatchDeleteDraft data) {
        // 获取表单信息
        SubmissionForm form = checkSubmissionForm(data.getFormId());

        // 获取数据源信息
        DataSource dataSource = checkDataSource(form.getDataSourceId());

        // 获取字段列表
        List<SubmissionFormField> fieldList = getFieldList(data.getFormId());

        // 删除数据
        DbUtil dbUtil = CommonDataUtil.getDbUtilInstance(dataSource);
        for (SubmissionDto.Id dto : data.getIdList()) {
            // 获取草稿数据
            Pageable pageable = DataUtils.pageable(1, 1, null, null);
            List<SubmissionFormField> whereList = new ArrayList<>();
            SubmissionFormField field = new SubmissionFormField();
            field.setFieldCode("ID");
            field.setFieldValue(dto.getId().toString());
            field.setLogicOperator((short) 1);
            field.setFieldDataType("VARCHAR");
            whereList.add(field);
            List<Map<String, Object>> dataList = dbUtil.page(form.getTableName(), fieldList, whereList, pageable);
            if (dataList == null || dataList.isEmpty()) {
                continue;
            }
            if (dataList.get(0).containsKey("ADD_BATCH_ID") && dataList.get(0).get("ADD_BATCH_ID") != null) {
                continue;
            }

            // 删除数据
            dbUtil.delete(form.getTableName(), whereList);
        }

        return new ResponseDto("操作成功");
    }


    /**
     * 批量提交草稿
     * @param data
     * @return
     */
    public ResponseDto batchSubmitDraft(SubmissionDto.BatchSubmitDraft data, UserDto user) {
        // 获取表单信息
        SubmissionForm form = checkSubmissionForm(data.getFormId());

        // 获取数据源信息
        DataSource dataSource = checkDataSource(form.getDataSourceId());

        // 获取字段列表
        List<SubmissionFormField> fieldList = getFieldList(data.getFormId());

        // 提交数据
        DbUtil dbUtil = CommonDataUtil.getDbUtilInstance(dataSource);
        int success = 0;
        List<SubmissionDto.ErrorMsg> errorMsgList = new ArrayList<>();
        for (SubmissionDto.Id dto : data.getIdList()) {
            // 获取草稿数据
            Pageable pageable = DataUtils.pageable(1, 1, null, null);
            List<SubmissionFormField> whereList = new ArrayList<>();
            SubmissionFormField field = new SubmissionFormField();
            field.setFieldCode("ID");
            field.setFieldValue(dto.getId().toString());
            field.setLogicOperator((short) 1);
            field.setFieldDataType("VARCHAR");
            whereList.add(field);
            List<Map<String, Object>> dataList = dbUtil.page(form.getTableName(), fieldList, whereList, pageable);
            if (dataList == null || dataList.isEmpty()) {
                continue;
            }
            if (dataList.get(0).containsKey("ADD_BATCH_ID") && dataList.get(0).get("ADD_BATCH_ID") != null) {
                continue;
            }

            // 校验数据
            JsonObject jsonObject = JsonUtil.objToJson(dataList.get(0));
            List<SubmissionDto.ErrorMsg> _errorMsgList = checkParams(fieldList, jsonObject, ADD_DATA_STATUS_1);
            if (_errorMsgList != null && !_errorMsgList.isEmpty()) {
                errorMsgList.addAll(_errorMsgList);
                continue;
            }

            // 保存批次信息
            SubmissionBatch submissionBatch = saveSubmissionBatch(data.getFormId(), SubmissionBatchType.TYPE_1.code, 1, user);

            // 保存数据
            JsonArray jsonArray = new JsonArray();
            jsonObject.addProperty("ID", dto.getId());
            jsonArray.add(jsonObject);
            saveData(dataSource, form, fieldList, submissionBatch, jsonArray, ADD_DATA_STATUS_1);

            success++;
        }

        // 单条返回格式
        Map<String, Object> map = new HashMap<>();
        map.put("total", data.getIdList().size());
        map.put("success", success);
        if (data.getIdList().size() == 1) {
            if (!errorMsgList.isEmpty()) {
                map.put("errorMsgList", errorMsgList);
                return new ResponseDto(1, "操作失败", map);
            } else {
                return new ResponseDto("操作成功", map);
            }
        }

        // 多条返回格式
        return new ResponseDto( "操作成功", map);
    }

    /**
     * 批量报送
     * @param formId
     * @param fileName
     * @param fileBytes
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDto batchSubmit(Integer formId, Integer batchId, String fileName, byte[] fileBytes, UserDto user) {
        // 获取表单信息
        SubmissionForm form = checkSubmissionForm(formId);

        // 获取数据源信息
        DataSource dataSource = checkDataSource(form.getDataSourceId());

        // 获取字段列表
        List<SubmissionFormField> fieldList = getFieldList(formId);

        // 获取数据
        ExcelTypeEnum excelType = ExcelTypeEnum.getTypeByFileName(fileName);
        String[] columns = new String[fieldList.size()];
        for (int i = 0; i < fieldList.size(); i++) {
            columns[i] = fieldList.get(i).getFieldCode();
        }
        JsonArray data = ExcelUtil.readExcel(fileBytes, excelType,columns, 1);

        // 校验数据
        List<SubmissionDto.ErrorMsg> errorList = new ArrayList<>();
        for (int i = 0; i < data.size(); i++) {
            JsonObject json = data.get(i).getAsJsonObject();
            List<SubmissionDto.ErrorMsg> errorMsgList = checkParams(fieldList, json, ADD_DATA_STATUS_1);
            errorList.addAll(errorMsgList);
            if (errorMsgList != null && !errorMsgList.isEmpty()) {
                for (SubmissionDto.ErrorMsg errorMsg : errorMsgList) {
                    errorMsg.setRowNumber(i + 2);
                }
            }
            if (errorList.size() > 100) {
                break;
            }
        }
        if (!errorList.isEmpty()) {
            return new ResponseDto(1, "提交失败", errorList);
        }

        // 保存文件
        String dataStr = DateTimeUtils.dateToString(new Date(), DateTimeUtils.YYYY_MM_DD);
        SftpUtil.SftpDto sftpDto = new SftpUtil.SftpDto();
        sftpDto.setSftpPath(sftpPath);
        sftpDto.setHost(host);
        sftpDto.setPort(port);
        sftpDto.setUsername(username);
        sftpDto.setPassword(password);
        sftpDto.setSavePath(dataStr);
        sftpDto.setFileName(UUID.randomUUID().toString() + "." + excelType.value);
        sftpDto.setFileInputStream(new ByteArrayInputStream(fileBytes));
        SftpUtil.uploadFile(sftpDto);

        // 保存批次信息
        SubmissionBatch submissionBatch = null;
        if (batchId != null) {
            submissionBatch = submissionBatchMapper.selectByPrimaryKey(batchId);
            if (submissionBatch == null) {
                throw new BusinessException("批次不存在");
            }
            if (!SubmissionBatchStatus.STATUS_0.code.equals(submissionBatch.getStatus())) {
                throw new BusinessException("非待处理状态的批次，不允许重新上传");
            }
        } else {
            submissionBatch = saveSubmissionBatch(formId, SubmissionBatchType.TYPE_2.code, data.size(), user);
        }
        submissionBatch.setSaveFileName(sftpDto.getFileName());
        submissionBatch.setUploadFileName(fileName);
        submissionBatch.setSavePath(sftpDto.getSavePath());
        submissionBatchMapper.updateByPrimaryKeySelective(submissionBatch);

        // 删除批次相关的数据
        if (batchId != null) {
            DbUtil dbUtil = CommonDataUtil.getDbUtilInstance(dataSource);
            List<SubmissionFormField> whereList = new ArrayList<>();
            SubmissionFormField field = new SubmissionFormField();
            whereList.add(field);
            field.setFieldCode("ADD_BATCH_ID");
            field.setFieldValue(batchId.toString());
            field.setFieldDataType("VARCHAR");
            field.setLogicOperator(LogicOperator.CASE_1.code);
            dbUtil.delete(form.getTableName(), whereList);
        }

        // 保存数据
        saveData(dataSource, form, fieldList, submissionBatch, data, ADD_DATA_STATUS_1);

        return new ResponseDto("提交成功");
    }

    /**
     * 校验表单
     *
     * @param formId
     */
    private SubmissionForm checkSubmissionForm(Integer formId) {
        SubmissionForm form = submissionFormMapper.selectByPrimaryKey(formId);
        if (form == null) {
            throw new BusinessException("表单不在存");
        }
        if (FormStatus.STATUS_0.code.equals(form.getStatus())) {
            throw new BusinessException("该报送功能正在升级维护，请稍后再试");
        }
        return form;
    }

    /**
     * 校验数据源
     *
     * @param dataSourceId
     */
    private DataSource checkDataSource(Integer dataSourceId) {
        DataSource dataSource = dataSourceMapper.selectByPrimaryKey(dataSourceId);
        if (dataSource == null) {
            throw new BusinessException("关联数据源不存在");
        }
        if (CommonStatus.STATUS_0.code.equals(dataSource.getStatus())) {
            throw new BusinessException("关联数据源无效");
        }
        DataBaseType dataBaseType = DataBaseType.getDataBaseTypeByCode(dataSource.getDatabaseType());
        if (dataBaseType == null) {
            throw new BusinessException("未知的数据源类型");
        }
        if (!DataBaseType.TYPE_2.code.equals(dataSource.getDatabaseType())) {
            throw new BusinessException("暂时不支持" + dataBaseType.value + "数据库");
        }

        return dataSource;
    }

    /**
     * 获取表单字段列表
     *
     * @param formId
     * @return
     */
    private List<SubmissionFormField> getFieldList(Integer formId) {
        SubmissionFormFieldExample example = new SubmissionFormFieldExample();
        SubmissionFormFieldExample.Criteria criteria = example.createCriteria();
        criteria.andFormIdEqualTo(formId);
        example.setOrderByClause("sort asc");
        List<SubmissionFormField> fieldList = submissionFormFieldMapper.selectByExample(example);
        if (fieldList == null || fieldList.isEmpty()) {
            throw new BusinessException("该表单没有字段");
        }
        return fieldList;
    }

    /**
     * 校验字段
     *
     * @param fieldList
     * @param data
     */
    private List<SubmissionDto.ErrorMsg> checkParams(List<SubmissionFormField> fieldList, JsonObject data, short dataType) {
        List<SubmissionDto.ErrorMsg> errorMsgList = new ArrayList<>();
        for (SubmissionFormField field : fieldList) {
            // 校验必填字段是否填写
            String value = data.has(field.getFieldCode()) ? data.get(field.getFieldCode()).getAsString() : null;
            if (FormFieldRequiredStatus.STATUS_1.code.equals(field.getRequired()) && dataType == ADD_DATA_STATUS_1) {
                if (StringUtils.isBlank(value)) {
                    errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "未填写"));
                    continue;
                }
            }

            // 长度校验
            if (field.getFieldLength() != null && StringUtils.isNotBlank(value)) {
                if (value.length() > field.getFieldLength()) {
                    errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "不得超过" + field.getFieldLength() + "个字符"));
                    continue;
                }
            }

            // 校验字数字字段是否合法
            if (value != null) {
                boolean result = FieldDataType_DM.isValidNumber(field.getFieldDataType(), value);
                if (!result) {
                    errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "无效数字"));
                    continue;
                }
            }

            // 校验文本输入类型
            if (FormFieldInputType.TYPE_1.code.equals(field.getInputType()) && StringUtils.isNotBlank(field.getRuleCfg()) && StringUtils.isNotBlank(value) && dataType == ADD_DATA_STATUS_1) {
                SubmissionFormFieldDto.Update1 dto = JsonUtil.fromJson(field.getRuleCfg(), SubmissionFormFieldDto.Update1.class);
                if (CommonStatus.STATUS_1.code.equals(dto.getCheckStatus()) && StringUtils.isNotBlank(dto.getRegularExpression())) {
                    System.out.println(dto.getRegularExpression() + "---" + value);
                    boolean result = StringUtil.matchByRegex(dto.getRegularExpression(), value);
                    if (!result) {
                        errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "不满足输入要求"));
                        continue;
                    }
                }
            }

            // 校验数字输入类型
            if (FormFieldInputType.TYPE_2.code.equals(field.getInputType()) && StringUtils.isNotBlank(field.getRuleCfg()) && StringUtils.isNotBlank(value)) {
                // 校验正则表达式
                SubmissionFormFieldDto.Update2 dto = JsonUtil.fromJson(field.getRuleCfg(), SubmissionFormFieldDto.Update2.class);
                if (CommonStatus.STATUS_1.code.equals(dto.getCheckStatus())) {
                    boolean result = StringUtil.matchByRegex(dto.getRegularExpression(), value);
                    if (!result) {
                        errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "不满足输入要求"));
                        continue;
                    }
                }

                // 校验取值范围
                if (dto.getMinValue() != null && Double.parseDouble(value) < dto.getMinValue()) {
                    errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "取值不能小于" + StringUtil.dealDoubleValue(dto.getMinValue())));
                    continue;
                }
                if (dto.getMaxValue() != null && Double.parseDouble(value) > dto.getMaxValue()) {
                    errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "取值不能大于" + StringUtil.dealDoubleValue(dto.getMaxValue())));
                    continue;
                }
            }

            // 校验时间输入是否满足格式要求
            if (FormFieldInputType.TYPE_4.code.equals(field.getInputType()) && StringUtils.isNotBlank(value)) {
                if (StringUtils.isBlank(field.getRuleCfg())) {
                    errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "时间格式输入规则未配置"));
                    continue;
                }
                SubmissionFormFieldDto.Update4 dto = JsonUtil.fromJson(field.getRuleCfg(), SubmissionFormFieldDto.Update4.class);
                if (!StringUtil.matchByDateFormat(dto.getDateFormat(), value)) {
                    errorMsgList.add(new SubmissionDto.ErrorMsg(field.getFieldCode(), field.getFieldName(), "时间格式输入有误"));
                    continue;
                }
            }
        }
        return errorMsgList;
    }

    /**
     * 保存批次信息
     *
     * @param formId
     * @param batchType
     * @param batchCount
     * @param user
     * @return
     */
    private SubmissionBatch saveSubmissionBatch(Integer formId, Short batchType, Integer batchCount, UserDto user) {
        SubmissionBatch submissionBatch = new SubmissionBatch();
        submissionBatch.setFormId(formId);
        submissionBatch.setType(batchType);
        submissionBatch.setDataCount(batchCount);
        submissionBatch.setCreateTime(new Date());
        submissionBatch.setCreatorId(user.getId());
        submissionBatch.setCreatorName(user.getUserName());
        submissionBatch.setOrgId(user.getOrgId());
        submissionBatch.setOrgName(user.getOrgName());
        submissionBatchMapper.insertSelective(submissionBatch);
        return submissionBatch;
    }

    /**
     * 保存数据
     * @param dataSource
     * @param submissionForm
     * @param fieldList
     * @param submissionBatch
     * @param data
     */
    private void saveData(DataSource dataSource, SubmissionForm submissionForm, List<SubmissionFormField> fieldList, SubmissionBatch submissionBatch, JsonArray data, short dataType) {
        DbUtil dbUtil = CommonDataUtil.getDbUtilInstance(dataSource);
        fieldList = JsonUtil.fromJsonArray(JsonUtil.toJson(fieldList), SubmissionFormField.class);

        // 新增字段
        SubmissionFormField field = null;
        if (dataType == ADD_DATA_STATUS_1) {
            field = new SubmissionFormField();
            field.setFieldCode("add_batch_id");
            field.setFieldDataType("VARCHAR");
            fieldList.add(field);
        }
        field = new SubmissionFormField();
        field.setFieldCode("add_creator_id");
        field.setFieldDataType("VARCHAR");
        fieldList.add(field);
        field = new SubmissionFormField();
        field.setFieldCode("add_creator_name");
        field.setFieldDataType("VARCHAR");
        fieldList.add(field);
        field = new SubmissionFormField();
        field.setFieldCode("add_org_id");
        field.setFieldDataType("VARCHAR");
        fieldList.add(field);
        field = new SubmissionFormField();
        field.setFieldCode("add_org_name");
        field.setFieldDataType("VARCHAR");
        fieldList.add(field);
        field = new SubmissionFormField();
        field.setFieldCode("add_data_md5");
        field.setFieldDataType("VARCHAR");
        fieldList.add(field);
        field = new SubmissionFormField();
        field.setFieldCode("add_data_status");
        field.setFieldDataType("VARCHAR");
        fieldList.add(field);

        // 给新增字段赋值
        for (int i = 0; i < data.size(); i++) {
            JsonObject json = data.get(i).getAsJsonObject();
            String data_md5 = SecurityUtils.toMD5(json.toString());
            if (dataType == ADD_DATA_STATUS_1) {
                json.addProperty("add_batch_id", submissionBatch.getId());
            }
            json.addProperty("add_creator_id", submissionBatch.getCreatorId());
            json.addProperty("add_creator_name", submissionBatch.getCreatorName());
            json.addProperty("add_org_id", submissionBatch.getOrgId());
            json.addProperty("add_org_name", submissionBatch.getOrgName());
            json.addProperty("add_data_md5", data_md5);
            json.addProperty("add_data_status", dataType);
        }

        try {
            // 如果提交上来的数据含有ID字段，说明是更新草稿或提交草稿，否则是新建
            if (data.size() == 1 && data.get(0).getAsJsonObject().has("ID")) {
                Long id = data.get(0).getAsJsonObject().get("ID").getAsLong();
                String where = " ID = " + id;
                dbUtil.update(submissionForm.getTableName(), fieldList, data.get(0).getAsJsonObject(), where);
            } else {
                dbUtil.insert(submissionForm.getTableName(), fieldList, data);
            }
        } catch (Exception e) {
            if (e instanceof BusinessException) {
                BusinessException be = (BusinessException) e;
                throw be;
            } else {
                LOGGER.error("报送失败", e);
                throw new BusinessException("服务器繁忙，请稍后再试");
            }
        }
    }
}